﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using Space.Model;
using Space.Model.Data;
using Space.Model.Entity;

namespace Space.Library
{
    class ShipPainter
    {
        private readonly Painter _painter;

        private Bitmap shipBitmap;
        private Graphics _shipG;
        private int ShipPadding;

        public ShipPainter(Painter painter)
        {
            _painter = painter;

            ShipPadding = Ssize / 5;

            shipBitmap = shipBitmap ?? new Bitmap(Ssize, Ssize);
            _shipG = Graphics.FromImage(shipBitmap);
        }

        /// <summary>
        /// Size of each square on game board.
        /// </summary>
        protected int Ssize
        {
            get { return Board.Ssize; }
        }

        public Bitmap CreateShipBitmap(Ship ship)
        {
            var model = ship.ShipModel;
            int relSize = Ssize / 3;

            _shipG.Clear(Color.Transparent);

            // Draw engine flare
            Image image = _painter.GetEngineImage("effect_engine_proton");
            var engineRect = new Rectangle(Ssize / 2 - relSize / 2, Ssize - relSize, relSize, relSize);
            _shipG.DrawImage(image, engineRect);

            DoShields(model);

            _shipG.DrawImage(_painter.GetShipModel(model), ShipPadding, ShipPadding, Ssize - ShipPadding * 2, Ssize - ShipPadding * 2);

            return shipBitmap;
        }

        private void DoShields(ShipModel model)
        {
            const int thickness = 10;

            var bounds = new Rectangle(0, 0, Ssize, Ssize);
            using (var ellipsePath = new GraphicsPath())
            {
                ellipsePath.AddEllipse(bounds);
                using (var brush = new PathGradientBrush(ellipsePath))
                {
                    brush.CenterPoint = new PointF(bounds.Width / 2f, bounds.Height / 2f);
                    brush.CenterColor = Color.FromArgb(0, 140, 0);
                    brush.SurroundColors = new[] { Color.FromArgb(0, 255, 0) };
                    brush.FocusScales = new PointF(0, 0);
                    brush.SetSigmaBellShape(0.2f); // Move center of gradient.

                    // Ship model front is upwards. Arcs start from 1500.
                    var pen = new Pen(brush);
                    DrawShield(pen, thickness, model.ShieldBottomStr, 50, 80);
                    DrawShield(pen, thickness, model.ShieldLeftStr, 140, 80);
                    DrawShield(pen, thickness, model.ShieldTopStr, 230, 80);
                    DrawShield(pen, thickness, model.ShieldRightStr, 320, 80);
                }
            }
        }

        private void DrawShield(Pen pen, float thickness, int strength, int angleStart, int degrees)
        {
            pen.Width = thickness;
            _shipG.DrawArc(pen, 0, 0, Ssize, Ssize, angleStart, degrees);

            if (strength < 100)
            {
                var transparentPen = new Pen(Color.Black);
                transparentPen.Width = thickness - strength * thickness / 100;
                _shipG.DrawArc(transparentPen, 0, 0, Ssize, Ssize, angleStart, degrees);
            }
        }
    }
}
